package com.afdor.rws.extension.factory;

import com.afdor.rws.annotation.extension.Extension;
import com.afdor.rws.core.extension.ExtensionFactory;
import com.afdor.rws.core.extension.ExtensionItem;
import com.afdor.rws.core.extension.utils.ExtensionUtils;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 基于Spring实现的扩展点扫描器工厂
 *
 * @author 悭梵
 * @date Created in 2018-09-13 17:41
 */
@Slf4j
@ToString
@EqualsAndHashCode
@Extension(value = "spring", order = Extension.MAX_ORDER - 100)
public class SpringExtensionFactory implements ExtensionFactory, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public <T> boolean hasExtension(Class<T> interfaceClass, String name) {
        return false;
    }

    @Override
    public <T> T newExtension(Class<T> interfaceClass, String name, Object... args) {
        throw new IllegalStateException("The extension managed by Spring can not be created.");
    }

    @Override
    public <T> T getExtension(Class<T> interfaceClass, String name) {
        return applicationContext.getBean(ExtensionUtils.getFullExtension(interfaceClass, name), interfaceClass);
    }

    @Override
    public <T> Collection<ExtensionItem<T>> loadExtensionClasses(Class<T> interfaceClass) {
        Map<String, T> springExtensionMap = applicationContext.getBeansOfType(interfaceClass);
     //   return Optional.ofNullable(springExtensionMap).orElse(Collections.emptyMap()).entrySet().stream().map(entry -> new ExtensionItem(entry.getKey(), entry.getValue().getClass())).collect(Collectors.toList());
        return Collections.emptyList();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
